package com.lxmes.business.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.lxmes.business.domain.CcDiscrepancyAdjustment;
import com.lxmes.business.domain.CcInventoryRules;
import com.lxmes.business.domain.CcStockInfo;
import com.lxmes.business.mapper.CcDiscrepancyAdjustmentMapper;
import com.lxmes.business.mapper.CcInventoryRulesMapper;
import com.lxmes.business.mapper.CcStockInfoMapper;
import com.lxmes.common.utils.DateUtils;
import com.lxmes.common.utils.SecurityUtils;
import com.lxmes.common.utils.bean.BeanUtils;
import com.lxmes.sales.domain.CcStockInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lxmes.common.utils.StringUtils;
import com.lxmes.common.utils.bean.BeanValidators;
import com.lxmes.common.exception.ServiceException;
import javax.validation.Validator;
import com.lxmes.business.mapper.CcStockInventoryMapper;
import com.lxmes.business.domain.CcStockInventory;
import com.lxmes.business.service.ICcStockInventoryService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 库存盘点管理Service业务层处理
 *
 * @author lx
 * @date 2023-06-29
 */
@Service
public class CcStockInventoryServiceImpl implements ICcStockInventoryService
{
    @Autowired
    private CcStockInventoryMapper ccStockInventoryMapper;

    @Autowired
    private CcInventoryRulesMapper ccInventoryRulesMapper;

    @Autowired
    private CcStockInfoMapper ccStockInfoMapper;

    @Autowired
    private CcDiscrepancyAdjustmentMapper ccDiscrepancyAdjustmentMapper;



    @Autowired
    protected Validator validator;
    /**
     * 查询库存盘点管理
     *
     * @param id 库存盘点管理主键
     * @return 库存盘点管理
     */
    @Override
    public CcStockInventory selectCcStockInventoryById(Long id)
    {
        return ccStockInventoryMapper.selectCcStockInventoryById(id);
    }

    /**
     * 查询库存盘点管理列表
     *
     * @param ccStockInventory 库存盘点管理
     * @return 库存盘点管理
     */
    @Override
    public List<CcStockInventory> selectCcStockInventoryList(CcStockInventory ccStockInventory)
    {
        return ccStockInventoryMapper.selectCcStockInventoryList(ccStockInventory);
    }

    /**
     * 新增库存盘点管理
     *
     * @param ccStockInventory 库存盘点管理
     * @return 结果
     */
    @Override
    public int insertCcStockInventory(CcStockInventory ccStockInventory)
    {
        ccStockInventory.setCreateTime(DateUtils.getNowDate());
        return ccStockInventoryMapper.insertCcStockInventory(ccStockInventory);
    }

    /**
     * 修改库存盘点管理
     *
     * @param ccStockInventory 库存盘点管理
     * @return 结果
     */
    @Override
    public int updateCcStockInventory(CcStockInventory ccStockInventory)
    {
        ccStockInventory.setUpdateTime(DateUtils.getNowDate());
        return ccStockInventoryMapper.updateCcStockInventory(ccStockInventory);
    }

    /**
     * 批量删除库存盘点管理
     *
     * @param ids 需要删除的库存盘点管理主键
     * @return 结果
     */
    @Override
    public int deleteCcStockInventoryByIds(Long[] ids)
    {
        return ccStockInventoryMapper.deleteCcStockInventoryByIds(ids);
    }

    /**
     * 删除库存盘点管理信息
     *
     * @param id 库存盘点管理主键
     * @return 结果
     */
    @Override
    public int deleteCcStockInventoryById(Long id)
    {
        return ccStockInventoryMapper.deleteCcStockInventoryById(id);
    }
    @Override
    public String imporIteminfo(List<CcStockInventory> ccStockInventoryList, boolean updateSupport, String operName) {
        if (StringUtils.isNull(ccStockInventoryList) || ccStockInventoryList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (CcStockInventory ccStockInventory : ccStockInventoryList)
        {
            try
            {
                BeanValidators.validateWithException(validator, ccStockInventory);
                ccStockInventory.setCreateBy(operName);
                ccStockInventory.setUpdateBy(operName);
                this.insertCcStockInventory(ccStockInventory);
                successNum++;
                successMsg.append("<br/>" + successNum + "数据导入成功");
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/> 数据导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     *
     * 1:按库位盘点 2:按照物料盘点
     *
     * */
    @Override
    @Transactional
    public int handleInventory(String inventoryWay) {
        ccStockInventoryMapper.emptyInventory();
//        ccDiscrepancyAdjustmentMapper.emptyInventory();
        CcInventoryRules ccInventoryRules = new CcInventoryRules();
        ccInventoryRules.setInventoryFlag("是");
        List<CcInventoryRules> ccInventoryRulesList = ccInventoryRulesMapper.selectCcInventoryRulesList(ccInventoryRules);
        CcStockInfo ccStockInfo = new CcStockInfo();

        for(CcInventoryRules inventoryRules : ccInventoryRulesList){
            //逐级递减 一级一级判断
            String locationCode = inventoryRules.getLocationCode();
            if(StringUtils.isNull(locationCode)){
                String areaCode = inventoryRules.getAreaCode();
                if(StringUtils.isNull(areaCode)){
                    ccStockInfo.setStockId(inventoryRules.getWarehouseCode());
                }else{
                    ccStockInfo.setKuquCode(areaCode);
                }
            }else{
                ccStockInfo.setKuweiCode(locationCode);
            }

            List<CcStockInfo> ccStockInfos = ccStockInfoMapper.selectCcStockInfoList(ccStockInfo);
            if("1".equals(inventoryWay)){
                for(CcStockInfo stockInfo : ccStockInfos){
                    CcStockInventory ccStockInventory = new CcStockInventory();
                    BeanUtils.copyProperties(stockInfo,ccStockInventory);
                    ccStockInventory.setInventoryCode("KW"+DateUtils.parseDateToStr("yyyyMMdd",new Date()));
                    ccStockInventory.setGenerateDate(new Date());
//                    ccStockInventory.setInventoryUser(SecurityUtils.getUsername());
                    ccStockInventory.setGenerateTime(new Date());
                    ccStockInventory.setTotalNum(stockInfo.getResourceLocking().add(stockInfo.getKyNum()));
                    ccStockInventory.setCyNum(ccStockInventory.getSpNum().subtract(ccStockInventory.getTotalNum()));
                    ccStockInventory.setSpNum(BigDecimal.valueOf(0));
                    ccStockInventory.setDeptId(SecurityUtils.getDeptId());
                    ccStockInventoryMapper.insertCcStockInventory(ccStockInventory);



                }
            } else if ("2".equals(inventoryWay)) {
                Map<String,List<CcStockInfo>> stockInfoMap = ccStockInfos.stream().collect(Collectors.groupingBy(CcStockInfo::getItemId));
                for (String key : stockInfoMap.keySet()) {
                    List<CcStockInfo> value = stockInfoMap.get(key);

                    BigDecimal KyTotalNum = value.stream().map(CcStockInfo::getKyNum).reduce((a, b) -> (a.add(b))).get();
                    BigDecimal RlTotalNum = value.stream().map(CcStockInfo::getResourceLocking).reduce((a, b) -> (a.add(b))).get();
                    CcStockInventory ccStockInventory = new CcStockInventory();
                    ccStockInventory.setGenerateDate(new Date());
//                    ccStockInventory.setInventoryUser(SecurityUtils.getUsername());
                    ccStockInventory.setGenerateTime(new Date());
                    ccStockInventory.setInventoryCode("WL"+DateUtils.parseDateToStr("yyyyMMdd",new Date()));
                    ccStockInventory.setTotalNum(KyTotalNum.add(RlTotalNum));
                    ccStockInventory.setKyNum(KyTotalNum);
                    ccStockInventory.setResourceLocking(RlTotalNum);
                    ccStockInventory.setFactoryCode(value.get(0).getFactoryCode());
                    ccStockInventory.setFactoryName(value.get(0).getFactoryName());
                    ccStockInventory.setItemCode(key);
                    ccStockInventory.setItemName(value.get(0).getItemName());
                    ccStockInventory.setItemId(key);
                    ccStockInventory.setSpec(value.get(0).getSpec());
                    ccStockInventory.setStockId(value.get(0).getStockId());
                    ccStockInventory.setStockName(value.get(0).getStockName());
                    ccStockInventory.setSpNum(BigDecimal.valueOf(0));
                    ccStockInventory.setDeptId(SecurityUtils.getDeptId());
                    ccStockInventoryMapper.insertCcStockInventory(ccStockInventory);
                }
            }
        }
        return 1;
    }

    @Override
    public List<CcStockInventory> selectCcStockInventoryMain(CcStockInventory ccStockInventory) {

        return ccStockInventoryMapper.selectCcStockInventoryMain(ccStockInventory);
    }

    @Override
    @Transactional
    public int inventoryJs(String inventoryCode) {
        CcStockInventory ccStockInventory = new CcStockInventory();
        ccStockInventory.setInventoryCode(inventoryCode);
        List<CcStockInventory> ccStockInventories = ccStockInventoryMapper.selectCcStockInventoryList(ccStockInventory);
        List<CcStockInventory> collect = ccStockInventories.stream().filter(in -> in.getState().equals("0")).collect(Collectors.toList());
        if(collect.size()>0){
            throw new RuntimeException("有未盘点的物料,暂不能进行核算！");
        }
        /*删除创建时间是今天的*/
        ccDiscrepancyAdjustmentMapper.emptyInventory();
        for(CcStockInventory stockInfo : ccStockInventories){
            if(stockInfo.getCyNum().longValue()!=0) {
                CcDiscrepancyAdjustment ccDiscrepancyAdjustment = new CcDiscrepancyAdjustment();
                ccDiscrepancyAdjustment.setCompanyCode(stockInfo.getFactoryCode());
                ccDiscrepancyAdjustment.setCompanyName(stockInfo.getFactoryName());
                ccDiscrepancyAdjustment.setInventoryDate(new Date());
                ccDiscrepancyAdjustment.setMaterialCode(stockInfo.getItemCode());
                ccDiscrepancyAdjustment.setMaterialSubcode(stockInfo.getItemId());
                ccDiscrepancyAdjustment.setMaterialName(stockInfo.getItemName());
                ccDiscrepancyAdjustment.setSpecification(stockInfo.getSpec());
                ccDiscrepancyAdjustment.setBatchNumber(stockInfo.getLot());
                ccDiscrepancyAdjustment.setMaterialUnit(stockInfo.getUnit());
                ccDiscrepancyAdjustment.setLocationQuantity(stockInfo.getTotalNum());
                ccDiscrepancyAdjustment.setLockedQuantity(stockInfo.getResourceLocking());
                ccDiscrepancyAdjustment.setAvailableQuantity(stockInfo.getKyNum());
                ccDiscrepancyAdjustment.setTotalQuantity(stockInfo.getTotalNum());
                ccDiscrepancyAdjustment.setActualQuantity(stockInfo.getSpNum());
                ccDiscrepancyAdjustment.setAdjustmentQuantity(stockInfo.getCyNum());
                ccDiscrepancyAdjustment.setCreateTime(DateUtils.getNowDate());
                ccDiscrepancyAdjustment.setCreateBy(SecurityUtils.getUsername());
                ccDiscrepancyAdjustment.setDeptId(SecurityUtils.getDeptId());
                ccDiscrepancyAdjustmentMapper.insertCcDiscrepancyAdjustment(ccDiscrepancyAdjustment);
            }
        }
        ccStockInventory.setAppShow("0");
        return ccStockInventoryMapper.updateCcStockInventoryByCode(ccStockInventory);
    }
}
